package com.cauli.file.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cauli.file.component.AsyncTaskComp;
import com.cauli.file.component.FileDealComp;
import com.cauli.file.mapper.FileMapper;
import com.cauli.file.mapper.ImageMapper;
import com.cauli.file.mapper.MusicMapper;
import com.cauli.file.mapper.UserFileMapper;
import com.cauli.file.model.entity.FileEntity;
import com.cauli.file.model.entity.Image;
import com.cauli.file.model.entity.Music;
import com.cauli.file.model.entity.UserFile;
import com.cauli.file.model.vo.file.FileDetailVO;
import com.cauli.file.service.FileService;
import com.cauli.file.utils.UserFileUtils;
import com.qiwenshare.common.exception.QiwenException;
import com.qiwenshare.common.operation.FileOperation;
import com.qiwenshare.ufop.factory.UFOPFactory;
import com.qiwenshare.ufop.operation.download.Downloader;
import com.qiwenshare.ufop.operation.download.domain.DownloadFile;
import com.qiwenshare.ufop.util.UFOPUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @author Cauli
 * @date 2023-03-20 12:00
 * @description 文件操作 服务实现类
 */
@Service
public class FileServiceImpl extends ServiceImpl<FileMapper, FileEntity> implements FileService {
    @Autowired
    private UserFileMapper userFileMapper;

    @Autowired
    private MusicMapper musicMapper;

    @Autowired
    private ImageMapper imageMapper;

    @Resource
    private UFOPFactory ufopFactory;

    @Resource
    private AsyncTaskComp asyncTaskComp;

    @Resource
    private FileDealComp fileDealComp;

    @Override
    public Long getFilePointCount(Long fileId) {
        LambdaQueryWrapper<UserFile> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserFile::getFileId, fileId);
        long count = userFileMapper.selectCount(lambdaQueryWrapper);
        return count;
    }

    @Override
    public void unzipFile(Long userFileId, int unzipMode, String filePath) {
        UserFile userFile = userFileMapper.selectById(userFileId);
        FileEntity fileEntity = baseMapper.selectById(userFile.getFileId());
        File destFile = new File(UFOPUtils.getStaticPath() + "temp" + File.separator + fileEntity.getFileUrl());

        Downloader downloader = ufopFactory.getDownloader(fileEntity.getStorageType());
        DownloadFile downloadFile = new DownloadFile();
        downloadFile.setFileUrl(fileEntity.getFileUrl());
        InputStream inputStream = downloader.getInputStream(downloadFile);

        try {
            FileUtils.copyInputStreamToFile(inputStream, destFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        String extendName = userFile.getExtendName();

        String unzipUrl = UFOPUtils.getTempFile(fileEntity.getFileUrl()).getAbsolutePath().replace("." + extendName, "");

        List<String> fileEntryNameList;

        try {
            fileEntryNameList = FileOperation.unzip(destFile, unzipUrl);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("解压失败" + e);
            throw new QiwenException(500001, "解压异常：" + e.getMessage());
        }

        if (destFile.exists()) {
            destFile.delete();
        }

        if (!fileEntryNameList.isEmpty() && unzipMode == 1) {
            UserFile qiwenDir = UserFileUtils.getUserDir(userFile.getUserId(), userFile.getFilePath(), userFile.getFileName());
            userFileMapper.insert(qiwenDir);
        }
        for (int i = 0; i < fileEntryNameList.size(); i++){
            String entryName = fileEntryNameList.get(i);
            asyncTaskComp.saveUnzipFile(userFile, fileEntity, unzipMode, entryName, filePath);
        }
    }

    @Override
    public void updateFileDetail(Long userFileId, String identifier, long fileSize) {
        UserFile userFile = userFileMapper.selectById(userFileId);
        FileEntity fileEntity = new FileEntity();
        fileEntity.setIdentifier(identifier);
        fileEntity.setFileSize(fileSize);
        fileEntity.setFileId(userFile.getFileId());
        baseMapper.updateById(fileEntity);
        userFileMapper.updateById(userFile);
    }

    @Override
    public FileDetailVO getFileDetail(Long userFileId) {
        UserFile userFile = userFileMapper.selectById(userFileId);
        FileEntity fileEntity = baseMapper.selectById(userFile.getFileId());
        Music music = musicMapper.selectOne(new QueryWrapper<Music>().eq("file_id", userFile.getFileId()));
        Image image = imageMapper.selectOne(new QueryWrapper<Image>().eq("file_id", userFile.getFileId()));

        if ("mp3".equalsIgnoreCase(userFile.getExtendName()) || "flac".equalsIgnoreCase(userFile.getExtendName())) {
            if (music == null) {
                fileDealComp.parseMusicFile(userFile.getExtendName(), fileEntity.getStorageType(), fileEntity.getFileUrl(), fileEntity.getFileId());
                music = musicMapper.selectOne(new QueryWrapper<Music>().eq("file_id", userFile.getFileId()));
            }
        }

        FileDetailVO fileDetailVO = new FileDetailVO();
        BeanUtil.copyProperties(userFile, fileDetailVO);
        BeanUtil.copyProperties(fileEntity, fileDetailVO);
        fileDetailVO.setMusic(music);
        fileDetailVO.setImage(image);
        return fileDetailVO;
    }
}
